#include "datacontainer.h"
#include <stdio.h>
//实际定义列表

//工具函数 定长比较
bool issame(byte *one,byte *two,int len)
{
    for(int i=0;i<len;++i)
        if(one[i]!=two[i]) return false;
    return true;
}
//寻找相同元素
int G_FindItem(void *lst, void *itemdata)
{
    List_void *vlst=CastToVoid(lst);
    byte *lstdata=vlst->data;
    for(int i=0;i<vlst->nowlen;++i)
    {
        if(issame(lstdata+vlst->unitsize*i,itemdata,vlst->unitsize))
        {
            return i;
        }
    }
    return -1;
}



void G_InitList(void *lst,int unitsize,int maxsize)
{
    //初始化
    List_void *vlst=CastToVoid(lst);
    vlst->maxlen=maxsize;
    vlst->nowlen=0;
    vlst->unitsize=unitsize;
    vlst->data=malloc(unitsize*maxsize);
}



void G_AddSize(List_void *vlst)
{
    //自动扩增容器大小 *1.5
    //新数据区
    int nmax=((int)vlst->nowlen*1.5)*vlst->unitsize;
    byte *buf=malloc(nmax);
    //复制数据
    memcpy(buf,vlst->data,vlst->nowlen*vlst->unitsize);
    void *t=vlst->data;
    vlst->data=buf;
    free(t);
    vlst->maxlen=(int)(vlst->nowlen*1.5);
}

bool G_AddItem(void *lst, void *item)
{
    List_void *vlst=CastToVoid(lst);

    if(vlst->nowlen<vlst->maxlen)
    {
        add:
        ;
        byte *data=vlst->data;
        memcpy(data+(vlst->nowlen*vlst->unitsize),item,vlst->unitsize);
        vlst->nowlen++;
        return true;
    }
    else
    {
        G_AddSize(vlst);
        goto add;//跳转到添加逻辑
    }
    //其他情况 未知 比如程序错误。。
    return false;
}


//这个函数不能工作就把下面的del操作转换为普通的循环实现
void memshift(void *buf,int step,int unitsize,int len)
{
    //移动 正数为右 负数为右
    //定义 下一个位置 i+1  放置位置 i+step 扫描过程 i=0 to len-1
    byte *nowbuf=malloc(unitsize);//当前缓冲区 用于存放当前操作的位置
    byte *nextbuf=malloc(unitsize); //临时缓冲区 用于存放下一个位置的数据
    byte *datas=buf; //数据指针
    //读取初始数据
    memcpy(nowbuf,datas,unitsize);
    memcpy(nextbuf,datas+1,unitsize);
    //存取过程 先把nowbuf复制到放置位置 然后把 nextbuf复制到nowbuf 如果i+2 并未超界限 则复制i+2位置数据到nextbuf
    for(int i=0;i<len;++i)
    {
        int seti=i+step;//生成放置位置
        memcpy(datas+seti,nowbuf,unitsize);
        memcpy(nowbuf,nextbuf,unitsize);
        if(i+2<len)
        {
            memcpy(nextbuf,datas+i+2,unitsize);
        }

    }
    free(nowbuf);
    free(nextbuf);
}
bool G_DelItem(void *lst, int idx)
{
    //从某个位置删除
    //左移

    List_void *vlst=CastToVoid(lst);
    if(idx<0||idx>=vlst->nowlen) return false;
    byte *data=vlst->data;
    //要移动数据开始的位置
    byte *srcptr=data+(idx+1)*vlst->unitsize;
    int movelen=vlst->nowlen-1-idx;
    byte *buf=malloc(movelen*vlst->unitsize);
    memcpy(buf,srcptr,movelen*vlst->unitsize);
    //复制左边位置
    memcpy(data+idx*vlst->unitsize,buf,movelen*vlst->unitsize);
    free(buf);
//    memshift(data+idx*vlst->unitsize+vlst->unitsize,-1,vlst->unitsize,vlst->nowlen-idx-1);
    vlst->nowlen--;
    return true;
}




List_byte Serialize(void *lst)
{
    //使用缓冲区建立数据缓存 除了原始数据  还保存元数据 即除了data指针外的list结构体数据
    //但不包括类型信息
    List_void *vlst=CastToVoid(lst);
    //此长度为list结构体的长度  不包括其中的data指针的长度
    int metalen=sizeof(List_void)-sizeof(void *);
    int fulllen=vlst->unitsize*vlst->nowlen+metalen;
    byte *buf=malloc(fulllen);
    memcpy(buf,lst,metalen);
    //计算列表数据存放位置
    byte *databuf=buf+metalen;
    memcpy(databuf,vlst->data,vlst->nowlen*vlst->unitsize);
    //生成ListByte
    List_byte ret=GenerateFromData(buf,fulllen);
    return ret;
}



List_void DeSerialize(List_byte data)
{
    //从头部复制并重置data指针
    List_void metalst=*(List_void *)(data.data);
    //初始化数据区 按原始的最大长度分配
    metalst.data=malloc(metalst.unitsize*metalst.maxlen);
    //复制数据
    int metalen=sizeof(List_void)-sizeof(void *);
    byte *datap=data.data+metalen;
    memcpy(metalst.data,datap,metalst.nowlen*metalst.unitsize);
    return metalst;
}



void WriteBytesToFile(List_byte bytes, const char *filename)
{
    FILE *f=fopen(filename,"wb");
    fwrite(&(bytes.nowlen),sizeof(int),1,f);
    fwrite(bytes.data,1,bytes.nowlen,f);
    fclose(f);
}



List_byte ReadBytesFromFile(const char *filename)
{
    FILE *f=fopen(filename,"rb");
    //读入头 得到后续数据长度
    int datalen;
    fread(&datalen,sizeof(int),1,f);
    byte *buf=malloc(datalen);
    fread(buf,1,datalen,f);
    //构建byteslist
    List_byte bytes;
    bytes.maxlen=bytes.nowlen=datalen;
    bytes.data=buf;
    bytes.unitsize=1;
    fclose(f);
    return bytes;
}



bool G_ListCopy(void *dst, void *src)
{
    List_void *vdst=CastToVoid(dst);
    List_void *vsrc=CastToVoid(src);
    byte *td=vdst->data;
    byte *fd=vsrc->data;
    if(vdst->unitsize!=vsrc->unitsize||vdst->maxlen<vsrc->nowlen)
    {
        //失败
        return false;
    }
    //复制
    memcpy(vdst->data,vsrc->data,vsrc->unitsize*vsrc->nowlen);
    return true;
}




List_byte GenerateFromData(void *data, int size)
{
    DefineList(byte,retlist);
    retlist.data=data;
    retlist.maxlen=size;
    retlist.nowlen=size;
    retlist.unitsize=1;
    return retlist;
}

DefineList(User,UserList) //定义用户列表 extern用于保证唯一性
DefineList(Activity,Activites) //活动表
DefineList(UserInfoItem,UserInfoList) //用户信息表
DefineList(Message,MessageList) //留言列表

//操作函数定义

